package cn.wgx.commons.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Java 反射工具类
 *
 * @author wgx
 */
public class ReflectionUtils {


    /**
     * 递归查找包括所有父类class内field属性
     *
     * @param clazz
     * @param name
     * @return
     */
    public static Field getField(Class clazz, String name) {
        Field f = null;
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.getName().equals(name)) {
                f = field;
                break;
            }
        }
        if (f == null) {
            Class superclass = clazz.getSuperclass();
            if (null != superclass && !(superclass.equals(Object.class))) {
                f = getField(superclass, name);
            }
        }
        return f;
    }

    /**
     * 获取Class所有field,包含继承的
     * @param clazz
     * @return
     */
    public static List<Field> getAllFields(Class clazz) {
        Field[] f = clazz.getDeclaredFields();
        List<Field> fields = new ArrayList(Arrays.asList(f));
        Class superclass = clazz.getSuperclass();
        if (null != superclass && !(superclass.equals(Object.class))) {
            List<Field> fields1 = getAllFields(superclass);
            if(!fields1.isEmpty()){
                fields.addAll(fields1);
            }
        }
        return fields;
    }

    /**
     * 反射获取 class 实例,待用
     *
     * @param clazz
     * @param objects
     * @param <E>
     * @return
     */
    private <E> E getInstance(Class<E> clazz, Object... objects) {
        int length = objects.length;
        Class[] classes = new Class[length];
        for (int i = 0; i < length; i++) {
            classes[i] = objects[i].getClass();
        }
        try {
            Constructor<E> constructor = clazz.getConstructor(classes);
            E e = constructor.newInstance(objects);
            return e;
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }


}
